// 
//  Copyright (C) 2009 Jacek Trubłajewicz
// 
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// 

using System;
using System.Drawing;
using System.IO;
using Mono.Unix;
using NLog;

namespace wxGadu
{
	
	
	public class ChangePasswordDialog : wx.Dialog
	{
		#region Id
		public enum Id
		{
		
		}
		#endregion
		
		#region controls
		private wx.StaticText oldPasswordST;
		private wx.StaticText newPasswordST;
		private wx.StaticText reNewPasswordST;
		private wx.StaticText uinST;
		private wx.StaticText emailST;
		private wx.TextCtrl uinTC;
		private wx.TextCtrl emailTC;
		private wx.TextCtrl oldPasswordTC;
		private wx.TextCtrl newPasswordTC;
		private wx.TextCtrl reNewPasswordTC;
		private wx.StaticBitmap logoSB;
		private wx.Button okButton;
		private wx.Button cancelButton;
		private wx.StaticBox staticBox;
		#endregion
		
		#region data members
		private MainFrame mainFrame;
		private Image token;
		#endregion
#if LOG
		private Logger logger = LogManager.GetCurrentClassLogger();
#endif
		
		public ChangePasswordDialog(wx.Window parent, int id, string title, Point pos, Size size, uint style):
			base(parent, id, title, pos, size, style)
		{
			mainFrame = (MainFrame) parent;
			
			DoControls();
			DoLayout();
			this.Size = new Size(300, 220);
			this.CenterOnScreen();
		}
		
		private void DoControls()
		{
			oldPasswordST = new wx.StaticText(this, Catalog.GetString("Old password:"));
			newPasswordST = new wx.StaticText(this, Catalog.GetString("New password:"));
			reNewPasswordST = new wx.StaticText(this, Catalog.GetString("Retype new password:"));
			uinST = new wx.StaticText(this, Catalog.GetString("Uin:"));
			emailST = new wx.StaticText(this, Catalog.GetString("New e-mail address:"));
			uinTC = new GGTextCtrl(this, wx.Window.wxID_ANY);
			emailTC = new wx.TextCtrl(this, wx.Window.wxID_ANY, string.Empty);
			oldPasswordTC = new wx.TextCtrl(this, wx.Window.wxID_ANY, string.Empty);
			oldPasswordTC.WindowStyle = wx.TextCtrl.wxTE_PASSWORD;
			newPasswordTC = new wx.TextCtrl(this, wx.Window.wxID_ANY, string.Empty);
			newPasswordTC.WindowStyle = wx.TextCtrl.wxTE_PASSWORD;
			reNewPasswordTC = new wx.TextCtrl(this, wx.Window.wxID_ANY, string.Empty);
			reNewPasswordTC.WindowStyle = wx.TextCtrl.wxTE_PASSWORD;
			logoSB = new wx.StaticBitmap(this, mainFrame.ImageMgr[ImageManager.PASSWORD_BIG]);
			okButton = new wx.Button(this, wx.Button.wxID_OK, Catalog.GetString("OK"));
			okButton.SetDefault();
			cancelButton = new wx.Button(this, wx.Button.wxID_CANCEL, Catalog.GetString("Cancel"));
			staticBox = new wx.StaticBox(this, Catalog.GetString("Personal data:"));
		}
		
		private void DoLayout()
		{
			wx.BoxSizer topSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
			{
				wx.BoxSizer boxSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
				{
					wx.StaticBoxSizer staticSizer = new wx.StaticBoxSizer(staticBox, wx.Orientation.wxHORIZONTAL);
					{
						staticSizer.Add(logoSB, 0, 0);
						
						wx.BoxSizer inputSizer = new wx.BoxSizer(wx.Orientation.wxVERTICAL);
						{
							inputSizer.Add(uinST, 0, 0);
							inputSizer.Add(uinTC, 0, wx.Stretch.wxEXPAND|wx.Direction.wxBOTTOM, 5);
							inputSizer.Add(emailST, 0, 0);
							inputSizer.Add(emailTC, 0, wx.Stretch.wxEXPAND);
							inputSizer.Add(oldPasswordST, 0, wx.Direction.wxTOP, 5);
							inputSizer.Add(oldPasswordTC, 0, wx.Stretch.wxEXPAND);
							inputSizer.Add(newPasswordST, 0, wx.Direction.wxTOP, 5);
							inputSizer.Add(newPasswordTC, 0, wx.Stretch.wxEXPAND);
							inputSizer.Add(reNewPasswordST, 0, wx.Direction.wxTOP, 5);
							inputSizer.Add(reNewPasswordTC, 0, wx.Stretch.wxEXPAND);
						}
						staticSizer.Add(inputSizer, 1, wx.Direction.wxLEFT, 5);
					}
					boxSizer.Add(staticSizer, 0, wx.Stretch.wxEXPAND);
					
					boxSizer.Add(20, 20, 1, 0, 0);
					
					wx.BoxSizer buttonSizer = new wx.BoxSizer(wx.Orientation.wxHORIZONTAL);
					{
						buttonSizer.Add(20, 20, 1, 0, 0);
						buttonSizer.Add(okButton, 0, 0);
						buttonSizer.Add(cancelButton, 0, wx.Direction.wxLEFT, 5);
					}
					boxSizer.Add(buttonSizer, 0, wx.Stretch.wxEXPAND);
				}
				topSizer.Add(boxSizer, 1, wx.Stretch.wxEXPAND|wx.Direction.wxALL, 5);
			}
			this.Sizer= topSizer;
			topSizer.SetSizeHints(this);
			topSizer.Fit(this);
		}
		
		public override bool TransferDataToWindow()
		{
			uinTC.Value = mainFrame.AppCfg.UserConf.Uin;
			
			return true;
		}
		
		public override bool TransferDataFromWindow()
		{
			wx.MessageDialog md;
			
			if (emailTC.Value.Trim() == string.Empty || oldPasswordTC.Value.Trim() == string.Empty || uinTC.Value.Trim() == string.Empty ||
			    newPasswordTC.Value.Trim() == string.Empty || reNewPasswordTC.Value.Trim() == string.Empty)
			{
				md = new wx.MessageDialog(this, Catalog.GetString("All fields cannot be empty"), 
				                          Catalog.GetString("Invalid data"), wx.MessageDialog.wxICON_ERROR|
				                          wx.MessageDialog.wxOK);
				md.ShowModal();
				return false;
			}
			
			if (newPasswordTC.Value.Trim() != newPasswordTC.Value.Trim())
			{
				md = new wx.MessageDialog(this, Catalog.GetString("New password must be identical in both fields"), 
				                          Catalog.GetString("Invalid data"), wx.MessageDialog.wxICON_ERROR|
				                          wx.MessageDialog.wxOK);
				md.ShowModal();
				return false;
			}
			
			if (emailTC.Value.Contains("@") == false || emailTC.Value.Trim().Length < 5)
			{
				md = new wx.MessageDialog(this, Catalog.GetString("Please provide valid e-mail address"), 
				                          Catalog.GetString("Invalid data"), wx.MessageDialog.wxICON_ERROR|
				                          wx.MessageDialog.wxOK);
				md.ShowModal();
				return false;
			}
			
			int uin;
			if (!Int32.TryParse(uinTC.Value, out uin))
			{
				md = new wx.MessageDialog(this, Catalog.GetString("Uin can contain only numeric characters"), 
				                          Catalog.GetString("Invalid data"), wx.MessageDialog.wxICON_ERROR|
				                          wx.MessageDialog.wxOK);
				md.ShowModal();
				return false;
			}
			
			// request token from GG server
			string tokenId, tokenUrl;
			wx.Utils.BeginBusyCursor();
			try
			{
				token = mainFrame.Dispatch.Gadu.GGGetToken(out tokenId, out tokenUrl);
			}
			catch (Exception e)
			{
#if LOG
				logger.ErrorException(Catalog.GetString("Error while receiving token image. Check your Internet connection"), e);
#endif
				md = new wx.MessageDialog(this,
		                                           String.Format(Catalog.GetString("Error while receiving token image. Check your Internet connection\n{0}"), e.Message),
		                                           Catalog.GetString("Connection error"),
		                                           wx.MessageDialog.wxICON_ERROR);
				md.ShowModal();
				return false;
			}
			finally
			{
				wx.Utils.EndBusyCursor();
			}
			// convert token to wx.Image
			MemoryStream ms = new MemoryStream();
			token.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);	
			byte[] imgByte = ms.ToArray();
			wx.Image tokenImg = new wx.Image(imgByte, wx.BitmapType.wxBITMAP_TYPE_JPEG);	
			wx.Bitmap tokenBmp = new wx.Bitmap(tokenImg);
			if (!tokenBmp.Ok())
			{
				md = new wx.MessageDialog(this, Catalog.GetString("Error while receiving token image. Check your Internet connection"), 
				                          Catalog.GetString("Connection error"), wx.MessageDialog.wxICON_ERROR|
				                          wx.MessageDialog.wxOK);
				md.ShowModal();
				return false;
			}

			TokenDialog tokenDlg = new TokenDialog(this, "Token", tokenBmp);
			tokenDlg.ShowModal();
			string tokenValue = tokenDlg.TokenVal;
			tokenDlg.Dispose();
			
			// send data to GG server
			bool success = false;
			try
			{
#if LOG
				logger.Trace("uin: {4}, email: {3}, tokenid: {0}, tokenval: {1}, tokenUrl: {2}", tokenId, tokenValue, tokenUrl, emailTC.Value, uin);
#endif
				success = mainFrame.Dispatch.Gadu.GGChangePassword(uin, oldPasswordTC.Value, newPasswordTC.Value, emailTC.Value, tokenId, tokenValue);
			}
			catch (Exception e)
			{
#if LOG
				logger.ErrorException(Catalog.GetString("Error while changing account password. Maybe you provided wrong token value."), e);
#endif
				md = new wx.MessageDialog(this,
		                                           String.Format(Catalog.GetString("Error while changing account password. Maybe you provided wrong token value.\n\n{0}"), e.Message),
		                                           Catalog.GetString("Error"),
		                                           wx.MessageDialog.wxICON_ERROR);
				md.ShowModal();
				
				return false;
			}
			
			if (!success)
			{
#if LOG
				logger.Error(Catalog.GetString("Error while changing account password. Maybe you provided wrong token value."));
#endif
				md = new wx.MessageDialog(this,
		                                           Catalog.GetString("Error while changing account password. Maybe you provided wrong token value"),
		                                           Catalog.GetString("Error"),
		                                           wx.MessageDialog.wxICON_ERROR);
				md.ShowModal();
				
				return false;
			}
			else
			{
#if LOG
				logger.Trace(Catalog.GetString("Successfuly changed account password"));
#endif
				md = new wx.MessageDialog(this,
		                                           Catalog.GetString("Successfuly changed account password"),
		                                           Catalog.GetString("Success"),
		                                           wx.MessageDialog.wxICON_ASTERISK);
				mainFrame.AppCfg.Password = newPasswordTC.Value;
				md.ShowModal();
			}
			
			return true;
		}
	}
}
